function varargout = FYP13CS063(varargin)
% FYP13CS063 MATLAB code for FYP13CS063.fig
%      FYP13CS063, by itself, creates a new FYP13CS063 or raises the existing
%      singleton*.
%
%      H = FYP13CS063 returns the handle to a new FYP13CS063 or the handle to
%      the existing singleton*.
%
%      FYP13CS063('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in FYP13CS063.M with the given input arguments.
%
%      FYP13CS063('Property','Value',...) creates a new FYP13CS063 or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before FYP13CS063_OpeningFcn gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to FYP13CS063_OpeningFcn via varargin.
%
%      *See GUI Options on GUIDE's Tools menu.  Choose "GUI allows only one
%      instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES

% Edit the above text to modify the response to help FYP13CS063

% Last Modified by GUIDE v2.5 06-Apr-2014 22:42:15

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
    'gui_Singleton',  gui_Singleton, ...
    'gui_OpeningFcn', @FYP13CS063_OpeningFcn, ...
    'gui_OutputFcn',  @FYP13CS063_OutputFcn, ...
    'gui_LayoutFcn',  [] , ...
    'gui_Callback',   []);
if nargin && ischar(varargin{1})
    gui_State.gui_Callback = str2func(varargin{1});
end

if nargout
    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
    gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT


% --- Executes just before FYP13CS063 is made visible.
function FYP13CS063_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% varargin   command line arguments to FYP13CS063 (see VARARGIN)

% Choose default command line output for FYP13CS063
handles.output = hObject;

% Update handles structure
guidata(hObject, handles);

% UIWAIT makes FYP13CS063 wait for user response (see UIRESUME)
% uiwait(handles.figure1);


% --- Outputs from this function are returned to the command line.
function varargout = FYP13CS063_OutputFcn(hObject, eventdata, handles)
% varargout  cell array for returning output args (see VARARGOUT);
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Get default command line output from handles structure
varargout{1} = handles.output;


% --- Executes on button press in exitButton.
function exitButton_Callback(hObject, eventdata, handles)
% hObject    handle to exitButton (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
clc
clear all
close(gcf);

% --- Executes on button press in loadButton.
function loadButton_Callback(hObject, eventdata, handles)
% hObject    handle to loadButton (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

clc;

global sX sX3;
sX3=[];
sX=[];

set(handles.OLPCalTimeText,'String','');
set(handles.textFile,'String','');
set(handles.text,'visible','off');
set(handles.editX,'String','');
set(handles.editX2,'String','');
set(handles.editX3,'String','');
set(handles.transformTimeText,'String','');
set(handles.calculateTimeText,'String','');
set(handles.calculateTimeText2,'String','');
set(handles.calButton,'visible','off');
set(handles.getButton,'visible','off');
set(handles.exportTransformButton,'visible','off');
set(handles.exportOriginalButton,'visible','off');
set(handles.exportTransformButton2,'visible','off');

[filename, pathname] = uigetfile({'*.xlsx';'*.xls'},'Choose a File','.xlsx');

if isequal(filename,0)
    errordlg('No file is selected', 'File Open Error');
    return;
end

str=[pathname, filename];
set(handles.textFile,'String',filename);

% Read Excel LP data
global c;

h = waitbar(0, 'Please wait, reading the file now...');

c=xlsread(str, 'c');
ALEqual=xlsread(str, 'A(<=)');
bLEqual=xlsread(str, 'b(<=)');
AGEqual=xlsread(str, 'A(>=)');
bGEqual=xlsread(str, 'b(>=)');
Aeq=xlsread(str, 'Aeq(=)');
beq=xlsread(str, 'beq(=)');
lb=xlsread(str, 'lb');

tic;
% Get no. of constraints and variables
global cRow;
[cRow cCol]= size(c);                
[ALEqualRow ALEqualCol]= size(ALEqual);                 % <=
[bLEqualRow bLEqualCol]= size(bLEqual);                 % <=
[AGEqualRow AGEqualCol]= size(AGEqual);                 % >=
[AeqRow AeqCol]= size(Aeq);                             % =

constraint = ALEqualRow + AGEqualRow + AeqRow;        % m
variable = max(ALEqualCol,max(AGEqualCol,AeqCol));    % n

noIneqConstraint = ALEqualRow + AGEqualRow;

slackVar = noIneqConstraint + variable;        % slack variable

% Transform import LP to standard form Ax <= b, Bx = 0
% Add zeros for c, B, Aeq, b
global nC nAeq nbeq;
nC = c;
nALEqual = ALEqual;
nAGEqual = AGEqual;
nAeq = Aeq;
nbeq = beq;

% New beq - combine sum of inequality and equality constraints
nbeq = [beq;bLEqual];
nbeq = [nbeq;bGEqual];

% Find no. of variables for displaying result
global cVariable;
cVariable = [];
n = 1;
for ii=1:1:cRow
    if c(ii) ~= 0
        cVariable(n,1) = ii;
        n = n + 1;
    end    
end

% New c
nC(slackVar,1) = 0;

% New Aeq
% (=)constraint
if (isempty(nALEqual)==0) || (isempty(nAGEqual)==0)
    if isempty(nAeq) == 0
        nAeq(AeqRow,slackVar)= 0;
    end
end

% (<=)constraint
if isempty(nALEqual) == 0
    nALEqual(ALEqualRow,slackVar)= 0;
    % add inequality constraints to new A
    nAeq=[nAeq;nALEqual];
end

% (>=)constraint
if isempty(nAGEqual) == 0
    nAGEqual(AGEqualRow,slackVar)= 0;
    % add inequality constraints to new A
    nAeq=[nAeq;nAGEqual];
end

% index of A (constraints) row
if isempty(nAeq)
    rowOfAeq = 1;
else
    rowOfAeq = 1 + AeqRow;
end

% index of A (constraints) column (slack variable)
colOfAeq = variable + 1;

% Aeq - add slack variable for inequality constraints forchanging to equality constraint
% New A & b - add inequality constraints for those constraints

global nA nb;
nA=[];
nb=[];
[lbRow lbCol] = size(lb);
nARow = 1;

% (=)constraint
% nA = zeros(colOfAeq-1,1);

% New A (lower bound from excel)
for ii=1:1:lbRow
    nA(nARow,nARow) = -1;
    nARow = nARow + 1;
end

% New b (lower bound from excel)
% nb = zeros(colOfAeq-1,1);
nb = lb;


% (<=)constraint
if isempty(nALEqual) == 0
    for ii=rowOfAeq:1:AeqRow + ALEqualRow
        nAeq(rowOfAeq,colOfAeq) = 1;
        nA(nARow,nARow) = -1;
        nb=[nb;0];
        rowOfAeq = rowOfAeq + 1;
        colOfAeq = colOfAeq + 1;
        nARow = nARow + 1;
    end
end

%(>=)constraint
if isempty(nAGEqual) == 0
    for ii=rowOfAeq:1:AeqRow + ALEqualRow + AGEqualRow
        nAeq(rowOfAeq,colOfAeq) = -1;
        nA(nARow,nARow) = -1;
        nb=[nb;0];       
        rowOfAeq = rowOfAeq + 1;
        colOfAeq = colOfAeq + 1;
        nARow = nARow + 1;
    end
end

waitbar(1,h,'Finish');
pause(1);
delete(h);

set(handles.calOrigButton,'visible','on');
set(handles.generateButton,'visible','on');

guidata(hObject,handles);

% --- Executes during object creation, after setting all properties.
function editConstraints_CreateFcn(hObject, eventdata, handles)
% hObject    handle to editConstraints (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --- Executes during object creation, after setting all properties.
function listboxObjective_CreateFcn(hObject, eventdata, handles)
% hObject    handle to listboxObjective (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: listbox controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

% --- Executes during object creation, after setting all properties.
function editX_CreateFcn(hObject, eventdata, handles)
% hObject    handle to editX (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --- Executes on button press in exportTransformButton.
function exportTransformButton_Callback(hObject, eventdata, handles)
% hObject    handle to exportTransformButton (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

global sX;
[filename, pathname]= uiputfile({'*.xlsx';'*.xls'}, 'Save as', 'Data.xlsx');

if isequal(filename,0) || isequal(pathname,0)
    errordlg('User selected Cancel', 'File Open Error');
    return;
else
    h = waitbar(0, 'Please wait, exporting the data now...');
end

str=[pathname, filename];

xlswrite(str, sX);

waitbar(1,h,'Finish');
pause(1);
delete(h);

% --- Executes on button press in generateButton.
function generateButton_Callback(hObject, eventdata, handles)
% hObject    handle to generateButton (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

set(handles.editX,'string', '');
set(handles.editX3,'string', '');
set(handles.exportTransformButton,'Visible', 'off');
set(handles.exportTransformButton2,'Visible', 'off');

global sX2;
if length(sX2) == 0
    set(handles.exportOriginalButton,'Visible', 'off');
end

global nC nA nAeq nbeq;
global M y r;
global cP AP bP nb AeqP beqP;
global nrowAeq ncolAeq;

tic;
%------------------------------M, r, y
[nrowAeq, ncolAeq] = size(nAeq);

% check Aeq has full row rank
if rank(nAeq)==nrowAeq
    fullRowRank=true;
end

if fullRowRank
    
    h = waitbar(0, 'Please wait, geting the solution now...');
    
    % generate a random n x n non-singular matrix M
    M = randi([0,5],ncolAeq);
    
    while det(M)==0
        M = randi([0,5],ncolAeq);
    end
    
    % generate a random n x 1 vector r
    r = randi([0,5],ncolAeq,1);
    
    while nbeq + nAeq * r == 0
        r = randi([0,5],ncolAeq,1);
    end
    
    % generate a random integer between 1 and 50
    gamma = round(rand(1)*49)+1;
    
    cP = gamma * M' * nC;           % c' = gM'c
    
    % -----------------------Q, A', b'
    % generate a m x m non-singular matrix Q (deteminant =/= 0)
    Q = randi([0,5],nrowAeq);
    
    while det(Q)==0
        Q = randi([0,5],nrowAeq);
    end
    
    AeqP = Q * nAeq * M;                    % A' = QAM
    beqP = Q * (nbeq + (nAeq * r));         % b' = Q(b + Ar)
        
    %-----------------------------B'
    [nrowAeqP, ncolAeqP] = size(AeqP);
    nonZero = nrowAeqP;         % find the non-zero of nbeq from end of the vector
    allZero = true;             % determine nbeq is all zero
    
    % find the non-zero of nbeq from end of the vector
    while nonZero ~= 0
        if beqP(nonZero) ~= 0
            allZero = false;            % found & exit loop
            break;
        end
        nonZero = nonZero - 1;
    end
    
    % generate a random n x m lambda
    Lambda =randi([0,5],ncolAeqP,nrowAeqP);
    sum = 0;      % sum of each row
    
    Br = nA * r;              % Br
    % change content of Lambda in order to cause Lambda * b' = Br
    if allZero == false
        if nonZero == 1
            % change first column of Lambda to zero
            for ii=1:1:ncolAeqP                  % row
                if nonZero == 1
                    Lambda(ii, 1) = 0;
                end
            end
        else
            for ii=1:1:ncolAeqP                  % row
                for jj=1:1:(nonZero-1)           % col
                    sum = sum + (Lambda(ii,jj) * beqP(jj));
                end
                Lambda(ii, nonZero) = (Br(ii) - sum) / beqP(nonZero);
                sum = 0;
            end
        end
    end    
 
    AP = (nA * M) - (Lambda * AeqP);         % B' = BM - (Lambda)QAM => BM-LA' =>(A' = AeqP)
    bP = (nA * r) - (Lambda * beqP);         % 0 = Br - Lambda(Q(b+Ar)) =>(Q(b+Ar) = beqP)

    % display transform Time
    toc
    set(handles.transformTimeText, 'String', toc);        
    
    set(handles.generateButton,'visible','off');
    set(handles.calButton,'visible','on');
    
    waitbar(1,h,'Finish');
    pause(1);
    delete(h);    
else
    errordlg('A does not has full row rank. Please select another LP problem with full row rank', 'Transform Error');
    return;
end

% --- Executes on button press in calButton.
function calButton_Callback(hObject, eventdata, handles)
% hObject    handle to calButton (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
global cP AP bP nb AeqP beqP;
global y fval exitflag sX;
global y3 fval3 exitflag3 sX3;

%     options = mskoptimset('MaxIter',4000000, 'Simplex','on','Write', 'prob.opf','Diagnostics','on');
options = mskoptimset('MaxIter',4000000);

tic;
[y,fval,exitflag] = linprog(cP,AP,nb,AeqP,beqP,[],[],[],options)
toc

% display calculate LP result
set(handles.calculateTimeText, 'String', num2str(toc));

% display x if x < 900
global cRow cVariable;

sX=[];

if exitflag > 0             % Normal: x is an optimal solution
    n=1;
    temp='Normal: The LP problem has an optimal solution.';
    sX{1,1}=temp;
    for ii=1:1:cRow
        if n <= length(cVariable)
            if ii == cVariable(n)
                temp = y(ii);
                sX{n+1,1} = ['x' num2str(ii) ' = ' num2str(temp)];
                n = n + 1;
            end
        end
    end
else if exitflag == 0       % Unbounded: Max. no. of iterations was reached
        sX{1,1} = 'Unbounded: Maximum number of iterations was reached.';
    else if exitflag < 0
            sX{1,1} = 'Infeasible: No solution.';
        end
    end
end
if cVariable < 900
    set(handles.editX,'string',sX);
else
    set(handles.text,'visible','on');
end

set(handles.textX,'visible','on');
set(handles.editX,'visible','on');
set(handles.editX3,'visible','on');
set(handles.calButton,'visible','off');
set(handles.getButton,'visible','on');

tic;
[y3,fval3,exitflag3] = linprog(cP,AP,bP,AeqP,beqP,[],[],[],options)
toc

% display calculate LP result
set(handles.calculateTimeText2, 'String', num2str(toc));

sX3=[];

if exitflag3 > 0             % Normal: x is an optimal solution
    n=1;
    temp='Normal: The LP problem has an optimal solution.';
    sX3{1,1}=temp;
    for ii=1:1:cRow
        if n <= length(cVariable)
            if ii == cVariable(n)
                temp = y(ii);
                sX3{n+1,1} = ['x' num2str(ii) ' = ' num2str(temp)];
                n = n + 1;
            end
        end
    end
else if exitflag == 0       % Unbounded: Max. no. of iterations was reached
        sX3{1,1} = 'Unbounded: Maximum number of iterations was reached.';
    else if exitflag < 0
            sX3{1,1} = 'Infeasible: No solution.';
        end
    end
end
if cVariable < 900
    set(handles.editX3,'string',sX3);
else
    set(handles.text,'visible','on');
end


% --- Executes on button press in getButton.
function getButton_Callback(hObject, eventdata, handles)
% hObject    handle to getButton (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
global M y r exitflag;
global sX sF sA;
global y3 exitflag3 sX3;

tic;
x = (M * y) - r;
toc
    
% display x
global cRow cVariable;

sX=[];
if exitflag > 0             % Normal: x is an optimal solution
    n=1;
    temp='Normal: The LP problem has an optimal solution.';
    sX{1,1}=temp;
    for ii=1:1:cRow
        if n <= length(cVariable)
            if ii == cVariable(n)
                temp = x(ii);
                sX{n+1,1} = ['x' num2str(ii) ' = ' num2str(temp)];
                n = n + 1;
            end
        end
    end
else if exitflag == 0       % Unbounded: Max. no. of iterations was reached
        sX{1,1} = 'Unbounded: Maximum number of iterations was reached.';
    else if exitflag < 0
            sX{1,1} = 'Infeasible: No solution.';
        end
    end
end

if cVariable < 900
    set(handles.editX,'string',sX);
else
    set(handles.text,'visible','on');
end

set(handles.getButton,'visible','off');
set(handles.calButton,'visible','off');
set(handles.exportTransformButton,'visible','on');
set(handles.generateButton,'visible','on');
set(handles.exportTransformButton2,'visible','on');

tic;
x3 = (M * y3) - r;
toc
sX3=[];
if exitflag3 > 0             % Normal: x is an optimal solution
    n=1;
    temp='Normal: The LP problem has an optimal solution.';
    sX3{1,1}=temp;
    for ii=1:1:cRow
        if n <= length(cVariable)
            if ii == cVariable(n)
                temp = x3(ii);
                sX3{n+1,1} = ['x' num2str(ii) ' = ' num2str(temp)];
                n = n + 1;
            end
        end
    end
else if exitflag3 == 0       % Unbounded: Max. no. of iterations was reached
        sX3{1,1} = 'Unbounded: Maximum number of iterations was reached.';
    else if exitflag3 < 0
            sX3{1,1} = 'Infeasible: No solution.';
        end
    end
end

if cVariable < 900
    set(handles.editX3,'string',sX3);
else
    set(handles.text,'visible','on');
end

% --- Executes on button press in calOrigButton.
function calOrigButton_Callback(hObject, eventdata, handles)
% hObject    handle to calOrigButton (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

global nC nA nb nAeq nbeq;

options = mskoptimset('MaxIter',4000000);

tic;
[x2,fval2,exitflag2]=linprog(nC,nA,nb,nAeq,nbeq,[],[],[],options)
toc

% display calculate original LP result
set(handles.OLPCalTimeText, 'String', num2str(toc));

% display x2 if x2 < 900
global cRow cVariable sX2;

n=1;
sX2=[];

if exitflag2 > 0             % Normal: x is an optimal solution
    temp='Normal: The LP problem has an optimal solution.';
    sX2{1,1}=temp;
    for ii=1:1:cRow
        if n <= length(cVariable)
            if ii == cVariable(n)
                temp = x2(ii);
                sX2{n+1,1} = ['x' num2str(ii) ' = ' num2str(temp)];
                n = n + 1;
            end
        end
    end
else if exitflag2 == 0       % Unbounded: Max. no. of iterations was reached
        sX2{1,1} = 'Unbounded: Maximum number of iterations was reached.';
    else if exitflag2 < 0
            sX2{1,1} = 'Infeasible: No solution.';
        end
    end
end

if cVariable < 900
    set(handles.editX2,'string',sX2);
else
    set(handles.text,'visible','on');
end

set(handles.exportOriginalButton,'visible','on');

% --- Executes during object creation, after setting all properties.
function editX2_CreateFcn(hObject, eventdata, handles)
% hObject    handle to editX2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --- Executes on button press in exportOriginalButton.
function exportOriginalButton_Callback(hObject, eventdata, handles)
% hObject    handle to exportOriginalButton (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

global sX2;

[filename, pathname]= uiputfile({'*.xlsx';'*.xls'}, 'Save as', 'Data.xlsx');

if isequal(filename,0) || isequal(pathname,0)
    errordlg('User selected Cancel', 'File Open Error');
    return;
else
    h = waitbar(0, 'Please wait, exporting the data now...');
end

str=[pathname, filename];
xlswrite(str, sX2);

waitbar(1,h,'Finish');
pause(1);
delete(h);

% --- Executes during object creation, after setting all properties.
function editX3_CreateFcn(hObject, eventdata, handles)
% hObject    handle to editX3 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --- Executes on button press in exportTransformButton2.
function exportTransformButton2_Callback(hObject, eventdata, handles)
% hObject    handle to exportTransformButton2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

global sX3;

[filename, pathname]= uiputfile({'*.xlsx';'*.xls'}, 'Save as', 'Data.xlsx');

if isequal(filename,0) || isequal(pathname,0)
    errordlg('User selected Cancel', 'File Open Error');
    return;
else
    h = waitbar(0, 'Please wait, exporting the data now...');
end

str=[pathname, filename];
xlswrite(str, sX3);

waitbar(1,h,'Finish');
pause(1);
delete(h);

function editX2_Callback(hObject, eventdata, handles)
% hObject    handle to editX2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of editX2 as text
%        str2double(get(hObject,'String')) returns contents of editX2 as a double
